import React, {useEffect, useState, useRef} from 'react';
import SerialPortModule from '../utils/SerialPortModule';
import BlobUtils from '../utils/BlobUtils';
import {get, post} from '../http/http';
import {ToastAndroid} from 'react-native';

const withSerialPort = WrappedComponent => {
  return props => {
    const address = '01';
    const handles = useRef({});
    const [locks, setLocks] = useState([]);
    const [openLock, setOpenLock] = useState(null);
    const [data, setData] = useState([]);
    const [products, setProducts] = useState([]);

    const materialCabinetId = props.route.params.materialCabinetId;
    useEffect(() => {
      checkAllState();
      return () => {
        Object.values(handles.current).forEach((v: any) => {
          clearInterval(v);
        });
      };
    }, []);

    const loadData = async () => {
      try {
        console.log('materialCabinetId:', materialCabinetId);
        const {data} = await get(
          '/assets/materialCabinetApi/api/queryMaterialCabinetRelListApi?route=assets',
          {
            limit: 999,
            materialCabinetId: materialCabinetId,
          },
        );
        const array = data.sort((a, b) => a.relNum - b.relNum);
        array.forEach(v => {
          if (parseInt(`${v.relNum}`, 10) <= 16) {
            v.address = '01';
            v.number = v.relNum;
          } else if (parseInt(`${v.relNum}`, 10) <= 40) {
            v.address = '02';
            v.number = parseInt(`${v.relNum}`, 10) - 16;
          } else {
            v.number = parseInt(`${v.relNum}`, 10) - 40;
            v.address = '03';
          }
        });
        setData(array);
      } catch (error) {}
    };

    const checkBoxManager = async completion => {
      try {
        const {data} = await get(
          '/assets/materialCabinet/api/getAssetsWarehousingAdminByUserId',
        );
        completion && completion(data);
        return data;
      } catch (error) {
        console.log(error.message);
      }
    };

    const checkAllState = () => {
      SerialPortModule.checkAll(address.trim(), data => {
        const state = data.replaceAll(' ', '');
        const all = state.substr(4, state.length - 8);
        const lockCount = all.length * 4;
        let locks = new Array(lockCount).fill(0);
        let m = 0;
        for (let i = all.length - 2; i >= 0; i = i - 2) {
          const s = all.substr(i, 2);
          const data = BlobUtils.numberToBinary(s);
          for (let j = 0; j < data.length; j++) {
            const c = data.charAt(7 - j);
            if (c === '1') {
              let number = m * 8 + j;
              locks[number] = 1;
            }
          }
          m++;
        }
        setLocks(locks);
      });
    };

    const checkLockState = (address, lock) => {
      if (handles.current[`${lock}`]) {
        clearInterval(handles.current[`${lock}`]);
      }
      handles.current[`${lock}`] = setInterval(() => {
        checkLock(address, lock);
      }, 2000);
    };

    const checkLock = (address, lock) => {
      SerialPortModule.checkLock(address, lock, data => {
        const state = data.replaceAll(' ', '');
        const all = state.substr(6, state.length - 8);
        const index = parseInt(lock, 16) - 1;
        if (all === '11') {
          setLocks(prevLocks => {
            const newLocks = [...prevLocks];
            newLocks[index] = 1;
            return newLocks;
          });
        } else {
          setLocks(prevLocks => {
            const newLocks = [...prevLocks];
            newLocks[index] = 0;
            return newLocks;
          });
          if (handles.current[`${lock}`]) {
            clearInterval(handles.current[`${lock}`]);
            handles.current[`${lock}`] = null;
          }
        }
      });
    };

    const whetherBoxIsLock = (address, lock, completion) => {
      SerialPortModule.checkLock(address, lock, data => {
        const state = data.replaceAll(' ', '');
        const all = state.substr(6, state.length - 8);
        const index = parseInt(lock, 16) - 1;
        completion && completion(all === '11');
        if (all === '11') {
          setLocks(prevLocks => {
            const newLocks = [...prevLocks];
            newLocks[index] = 1;
            return newLocks;
          });
        } else {
          setLocks(prevLocks => {
            const newLocks = [...prevLocks];
            newLocks[index] = 0;
            return newLocks;
          });
          if (handles.current[`${lock}`]) {
            clearInterval(handles.current[`${lock}`]);
            handles.current[`${lock}`] = null;
          }
        }
      });
    };

    const checkAndOpenBox = item => {
      let value = parseInt(`${item.number}`, 10).toString(16);
      if (value.length === 1) {
        value = '0' + value;
      }
      console.log('value:', value);
      whetherBoxIsLock(item.address, value, open => {
        if (open) {
          ToastAndroid.show('需要先把柜门关上', ToastAndroid.SHORT);
        } else {
          ToastAndroid.show('准备打开柜门', ToastAndroid.SHORT);
          setTimeout(() => {
            openBox(value, item);
          }, 300);
        }
      });
    };

    const openBox = (item, completion) => {
      let value = parseInt(`${item.number}`, 10).toString(16);
      if (value.length === 1) {
        value = '0' + value;
      }
      SerialPortModule.openLock(item.address, value, data => {
        const state = data.replaceAll(' ', '');
        const all = state.substr(6, state.length - 8);
        if (all === '11') {
          setOpenLock(item.relNum);
          ToastAndroid.show(
            '柜门已打开, 存放完成请记得关闭柜门',
            ToastAndroid.SHORT,
          );
        }
        completion && completion(value);
      });
    };

    return (
      <WrappedComponent
        {...props}
        data={data}
        products={products}
        locks={locks}
        openLock={openLock}
        loadData={loadData}
        checkLockState={checkLockState}
        checkBoxManager={checkBoxManager}
        checkAndOpenBox={checkAndOpenBox}
        whetherBoxIsLock={whetherBoxIsLock}
        openBox={openBox}
      />
    );
  };
};

export default withSerialPort;
